package com.ruoyi.dm.component.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.dm.domain.BO.ShapeDataBO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 姿态数据
 * 根据上传的卫星,自动建表,并存数据
 */
@Slf4j
@Component
public class ShapeDataManager {


    @Autowired
    JdbcTemplate jdbcTemplate;

    //序列
    //private String sequenceSql ="create sequence %s_seq start with 1 increment by 1";

    //监测
    private String checkSql ="select 1 from %s limit 1";

    //建索引
    private String indexSql ="CREATE INDEX %s_TIME ON PIESAT_DGDQ.%s (EPOCH_TIME)";

    //建索引
    private String creatDbSql = "CREATE TABLE %s ( ID SERIAL PRIMARY KEY , QX DECIMAL,QY DECIMAL, QZ DECIMAL,QS DECIMAL,EPOCH_TIME timestamp)" +
            "PARTITION BY RANGE (EPOCH_TIME) ("+
            "PARTITION P1 VALUES LESS THAN ('2000-01-01')," +
            "PARTITION P2 VALUES LESS THAN ('2002-01-01')," +
            "PARTITION P3 VALUES LESS THAN ('2004-01-01')," +
            "PARTITION P4 VALUES LESS THAN ('2006-01-01')," +
            "PARTITION P5 VALUES LESS THAN ('2008-01-01')," +
            "PARTITION P6 VALUES LESS THAN ('2010-01-01')," +
            "PARTITION P7 VALUES LESS THAN ('2012-01-01')," +
            "PARTITION P8 VALUES LESS THAN ('2014-01-01')," +
            "PARTITION P9 VALUES LESS THAN ('2016-01-01')," +
            "PARTITION P10 VALUES LESS THAN ('2018-01-01')," +
            "PARTITION P11 VALUES LESS THAN ('2020-01-01')," +
            "PARTITION P12 VALUES LESS THAN ('2022-01-01')," +
            "PARTITION P13 VALUES LESS THAN ('2024-01-01')," +
            "PARTITION P14 VALUES LESS THAN ('2026-01-01')," +
            "PARTITION P15 VALUES LESS THAN ('2028-01-01')," +
            "PARTITION P16 VALUES LESS THAN ('2030-01-01')," +
            "PARTITION P17 VALUES LESS THAN ('2032-01-01')," +
            "PARTITION P18 VALUES LESS THAN ('2034-01-01')," +
            "PARTITION P19 VALUES LESS THAN ('2036-01-01')," +
            "PARTITION P20 VALUES LESS THAN ('2100-01-01') )";

    //备注
    private String commont1  = "comment on column %s.QX  IS 'qx'";
    private String commont2  = "comment on column %s.QY  IS 'qy'";
    private String commont3  = "comment on column %s.QZ  IS 'qz'";
    private String commont4  = "comment on column %s.QS  IS 'qs'";
    private String commont5  = "comment on column %s.EPOCH_TIME  IS '观测时间'";

    private String commont6  = "comment on table %s  IS '卫星姿态记录表'";

    private String columnSql = "insert into %s (QX,QY,QZ,QS,EPOCH_TIME) values";

    private String valueSql = "('%s','%s','%s','%s','%s')";


    /**
     * 保存卫星数据
     * @param satellite
     * @param list
     */
    public void saveData(String satellite, List<ShapeDataBO> list) {

        if (!StringUtils.hasLength(satellite)) {
            throw new ServiceException("卫星名字不得为空");
        }

        String tableName = "COLLECT_ATTI_"+satellite.toUpperCase();

        dbCheck(tableName);

        List<List<ShapeDataBO>> split = CollectionUtil.split(list, 1000);
        for (List<ShapeDataBO> part : split) {
            String insert = String.format(columnSql, tableName);
            if (part.size()==1) {
                ShapeDataBO bo = part.get(0);
                jdbcTemplate.execute(insert +String.format(valueSql,bo.getQx(),bo.getQy(),bo.getQz(),bo.getQs(), DateUtil.format(bo.getEpoch_time(),"yyyy-MM-dd HH:mm:ss")));
            }else {
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(insert);
                for (ShapeDataBO bo : part) {
                    stringBuffer.append(String.format(valueSql,bo.getQx(),bo.getQy(),bo.getQz(),bo.getQs(),DateUtil.format(bo.getEpoch_time(),"yyyy-MM-dd HH:mm:ss")));
                    stringBuffer.append(",");
                }
                //去掉最后的逗号
                stringBuffer.deleteCharAt(stringBuffer.length()-1);
                jdbcTemplate.execute(stringBuffer.toString());
            }
        }
    }

    /**
     * 监测是否需要创建表,若需要则创建
     * @param tableName
     */
    private   void dbCheck(String tableName) {
        try {
            jdbcTemplate.execute(String.format(checkSql,tableName));
            log.info("监测表已存在:{}",tableName);
        }catch (BadSqlGrammarException e) {
            try {
                log.info("创建表:{}",tableName);
                createDb(tableName);
            }catch (Exception ee) {
                log.error("",ee);
                throw new ServiceException("创建表异常");
            }
            //if (cause instanceof DMException) {
            //    DMException dm = (DMException) cause;
            //    if (-2106 == dm.getErrorCode()) {
            //        //无效的表或视图 去创建
            //        log.info("监测表不存在,去创建:{}",tableName);
            //        createDb(tableName);
            //    }else {
            //        throw new ServiceException("创建表异常");
            //    }
            //}
        }catch (Exception e) {
            log.error("",e);
            throw new ServiceException("表异常");
        }

    }

    /**
     * 创建序列,建表,索引
     * @param tableName
     */
    private void createDb(String tableName) {
        //try {
        //    jdbcTemplate.execute(String.format(sequenceSql, tableName));
        //}catch (Exception e) {
        //    log.info("序列已存在");
        //}
        jdbcTemplate.execute(String.format(creatDbSql,tableName,tableName));
        jdbcTemplate.execute(String.format(commont1,tableName));
        jdbcTemplate.execute(String.format(commont2,tableName));
        jdbcTemplate.execute(String.format(commont3,tableName));
        jdbcTemplate.execute(String.format(commont4,tableName));
        jdbcTemplate.execute(String.format(commont5,tableName));
        jdbcTemplate.execute(String.format(commont6,tableName));
        try {
            jdbcTemplate.execute(String.format(indexSql, tableName, tableName));
        }catch (Exception e) {
            log.error("",e);
            log.info("索引已存在");
        }
    }


}
